﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace MedicalSystems
{
    public partial class Filter : Form
    {
        private List<string> names;
        private List<string> param;
        private List<Record> filter;
        DateTime fromTime;
        DateTime toTime;
        DateTime txnfromTime;
        DateTime txnToTime;
        private DataSourceBuilder dsb;

        public Filter()
        {
            InitializeComponent();
            this.filter = new List<Record>();
            fromTime = Globals.CURRENT_DATE.AddDays(-60);
            txnfromTime = Globals.CURRENT_DATE.AddDays(-60);
            txnToTime = Globals.CURRENT_DATE;
            toTime = Globals.CURRENT_DATE;
            this.dsb = new DataSourceBuilder();
        }

        private void clearFilter()
        {
            this.grdFilter.DataSource = null;
            initFilters();

            //this.grdFilter = new DataGridView();
            this.grdFilter.DataSource = this.filter;
            this.grdFilter.Refresh();
        }

        private void Filter_Load(object sender, EventArgs e)
        {
            clearFilter();

            this.grdFilter.DataSource = this.filter;
            dtTo.Value = Globals.CURRENT_DATE;
            dtFrom.Value = Globals.CURRENT_DATE.AddDays(-60);

            dtTxnFrom.Value = Globals.CURRENT_DATE.AddDays(-60);
            dtTxnTo.Value = Globals.CURRENT_DATE;

            //clearFilter();
        }

        private void initFilters()
        {
            this.filter.Clear();
            foreach (Record r in Globals.dataSet)
            {
                this.filter.Add(r);
            }
            reinitFilter();
            cmbName.SelectedIndex = 0;
            cmbParam.SelectedIndex = 0;
        }

        private void grdFilter_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {

        }

        private void reinitFilter()
        {
            names = (from r in filter
                     select r.FullName).Distinct().ToList();
            names.Add("All");
            names.Reverse();

            param = (from r in filter
                     select r.Parameter).Distinct().ToList();
            param.Add("All");
            param.Reverse();

            cmbName.DataSource = names;
            cmbParam.DataSource = param;
            dtFrom.Value = Globals.CURRENT_DATE.AddDays(-60);
            dtTxnFrom.Value = Globals.CURRENT_DATE.AddDays(-60);
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            clearFilter();
        }

        private void changeTo()
        {
            toTime = Convert.ToDateTime(dtTo.Value.ToShortDateString() + " " + cmbTo.Text);
        }

        private void cbFrom_CheckedChanged(object sender, EventArgs e)
        {
            dtFrom.Enabled = !cbFrom.Checked;
            cmbFrom.Enabled = !cbFrom.Checked;
            if (cbFrom.Checked)
            {
                dtFrom.Value = Globals.CURRENT_DATE;
            }
            else
            {
                cmbFrom.SelectedIndex = 0;
            }
        }

        private void cbTo_CheckedChanged(object sender, EventArgs e)
        {
            dtTo.Enabled = !cbTo.Checked;
            cmbTo.Enabled = !cbTo.Checked;
            if (cbTo.Checked)
            {
                dtTo.Value = Globals.CURRENT_DATE;
            }
            else
            {
                cmbTo.SelectedIndex = 0;
            }
        }

        private void dtTo_ValueChanged(object sender, EventArgs e)
        {
            changeTo();
        }

        private void cmbTo_SelectedIndexChanged(object sender, EventArgs e)
        {
            changeTo();
        }

        private void dtFrom_ValueChanged(object sender, EventArgs e)
        {
            changeFrom();
        }

        private void changeFrom()
        {
            fromTime = Convert.ToDateTime(dtFrom.Value.ToShortDateString() + " " + cmbFrom.Text);
        }

        private void cmbFrom_SelectedIndexChanged(object sender, EventArgs e)
        {
            changeFrom();
        }

        private void cbTxnTo_CheckedChanged(object sender, EventArgs e)
        {
            dtTxnTo.Enabled = !cbTxnTo.Checked;
            cmbTxnTo.Enabled = !cbTxnTo.Checked;
            if (cbTxnTo.Checked)
            {
                dtTxnTo.Value = Globals.CURRENT_DATE;
            }
            else
            {
                cmbTxnTo.SelectedIndex = 0;
            }
        }

        private void cbTxnFrom_CheckedChanged(object sender, EventArgs e)
        {
            dtTxnFrom.Enabled = !cbTxnFrom.Checked;
            cmbTxnFrom.Enabled = !cbTxnFrom.Checked;
            if (cbTxnFrom.Checked)
            {
                dtTxnFrom.Value = Globals.CURRENT_DATE;
            }
            else
            {
                cmbTxnFrom.SelectedIndex = 0;
            }
        }


        private void changeTxnTo()
        {
            txnToTime = Convert.ToDateTime(dtTxnTo.Value.ToShortDateString() + " " + cmbTxnTo.Text);
        }

        private void changeTxnFrom()
        {
            txnfromTime = Convert.ToDateTime(dtTxnFrom.Value.ToShortDateString() + " " + cmbTxnFrom.Text);
        }

        private void dtTxnFrom_ValueChanged(object sender, EventArgs e)
        {
            
        }

        private void btnFilter_Click(object sender, EventArgs e)
        {
            
            string param = "List<MedicalSystems.Record> ans = (from r in Globals.dataSet "
                                    + " where (r.startTime >= Convert.ToDateTime(\"" + dtFrom.Value.ToString() + "\") "
                                    + "&& r.finishTime <= Convert.ToDateTime(\"" + dtTo.Value.ToString() + "\") "
                                    + "&& r.txnStartTime <= Convert.ToDateTime(\"" + dtTxnFrom.Value.ToString() + "\") "
                                    + "&& ((!r.hasHinishTXN()) || (r.txnFinishTime >= Convert.ToDateTime(\"" + dtTxnTo.Value.ToString() + "\"))) ";
            if (cmbName.Text != "All") param += "&& (r.FullName == \"" + cmbName.Text + "\") ";
            if (cmbParam.Text != "All") param += "&& (r.Parameter == \"" + cmbParam.Text + "\") ";
                
            param += ") select r).ToList();return ans;";
            this.filter = dsb.dynamicList(param);

            if (!cbDerived.Checked || cmbDerived.SelectedIndex == 0)
            {
                reinitFilter();
                grdFilter.DataSource = this.filter;
                grdFilter.Refresh();
            }
            else
            {
                switch (cmbDerived.SelectedIndex)
                {
                    case 1:
                        Globals.derived = getHemoglobinState((from x in this.filter
                                                                   where x.Parameter == "Hemoglobin value"
                                                                   select x).ToList());
                        break;
                    case 2:
                        Globals.derived = getHematologicalState((from x in this.filter
                                                              where (x.Parameter == "Hemoglobin value" || x.Parameter == "WBC count")
                                                              select x).ToList());
                        break;
                    case 3:
                        break;
                    default:
                        break;
                }
                DerivedFilter df = new DerivedFilter();
                df.Show();
            }
        }

        private List<DerivedRecord> getHematologicalState(List<Record> list)
        {
            ClassificationTable ct = new ClassificationTable();
            List<Record> hemo = (from x in list
                                 where x.Parameter == "Hemoglobin value"
                                 select x).ToList();

            List<Record> wbc = (from x in list
                                 where x.Parameter == "WBC count"
                                 select x).ToList();

            List<DerivedRecord> tmp = new List<DerivedRecord>();
            foreach (Record r in hemo)
            {
                foreach (Record w in wbc)
                {
                    if (r.FullName == w.FullName)
                    {
                        Intersection i = ct.intersecs(r, w);
                        if (i != null)
                        {
                            string ans = ct.getHematologicalState(r, w);
                            DerivedRecord dr = new DerivedRecord(r, i, cmbDerived.Text, ans);
                            dr.Unit = "NA";
                            tmp.Add(dr);
                        }
                    }
                }
            }
            return tmp;
        }

        private List<DerivedRecord> getHemoglobinState(List<Record> list)
        {
            ClassificationTable ct = new ClassificationTable();
            List<DerivedRecord> tmp = new List<DerivedRecord>();
            foreach (Record r in list)
            {
                string ans = ct.getHemoglobinState(r);
                DerivedRecord dr = new DerivedRecord(r, ct.intersecs(r, r), cmbDerived.Text, ans);
                dr.Unit = "NA";
                tmp.Add(dr);
            }

            return tmp;
        }

        private void cbDerived_CheckedChanged(object sender, EventArgs e)
        {
            cmbDerived.Enabled = cbDerived.Checked;
        }
    }
}
